package com.choudou5.solr.searchrule;

import cn.hutool.core.collection.CollUtil;
import com.choudou5.solr.analyzer.bean.TermBean;
import com.choudou5.solr.analyzer.utils.PinyinUtil;
import com.choudou5.solr.bean.common.PageBean;
import com.choudou5.solr.bean.common.SolrQueryParam;
import com.choudou5.solr.service.ServiceHelper;
import com.choudou5.solr.service.SolrElevateService;
import com.choudou5.solr.util.LogDeBugUtil;
import com.choudou5.solr.util.StrUtil;
import com.choudou5.solr.util.WordSegmUtil;
import com.choudou5.solr.util.emoji.EmojiUtil;
import org.apache.solr.client.solrj.SolrQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * Desc：Solr查询规则 接口
 * Author：choudou5
 * Date：2018/7/17
 */
public class SolrQueryRuleService {

    private static Logger logger = LoggerFactory.getLogger(SolrQueryRuleService.class);

    public static final String DEFAULT_QUERY = "*:*";//默认查询
    public static final String SMALL_DATE = "1949-01-01T01:00:00Z";
    public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    public static final int MAX_PAGE_NO = 200;

    private final static SolrElevateService solrElevateService = ServiceHelper.singleton(SolrElevateService.class);

    public static SolrQueryParam getQueryRule(String solrModule, String keyword, PageBean pageBean){
        return getQueryRule(false, solrModule, keyword, pageBean);
    }

    /**
     * 获取 查询规则
     * @param solrModule
     * @param keyword
     * @return
     */
    public static SolrQueryParam getQueryRule(boolean isApi, String solrModule, String keyword, PageBean pageBean){
        SolrQueryParam query = new SolrQueryParam(solrModule, keyword);
        switch (solrModule){
            case "qa":
                if(isApi){
                    setQAApiQueryRule(query, keyword);
                }else{
                    setQAQueryRule(query, keyword);
                }
                break;
            case "goods":
                setGoodsQueryRule(query, keyword);
                break;
        }
        //设置竞价排名
        setElevate(query, solrModule, keyword);
        //设置分页
        setPage(query, pageBean);
        return query;
    }

    private static void setElevate(SolrQueryParam query, String solrModule, String keyword){
        //关键字
        if(StrUtil.isNotBlank(keyword)){
            List<String> docIds = solrElevateService.findCache(solrModule, keyword);
            if(CollUtil.isNotEmpty(docIds)){
                query.set("elevateIds", StrUtil.join(",", docIds));
            }
        }
    }


    /**
     * 获取 问题库 查询规则
     * @param keyword
     * @return
     */
    private static void setQAQueryRule(SolrQueryParam query, String keyword){
        //关键字
        if(StrUtil.isBlank(keyword)){
            query.setQuery(DEFAULT_QUERY);
            query.setSort("createTime", SolrQuery.ORDER.desc);
        }else{
            keyword = filterKeyword(keyword); //过滤 关键字 （过滤 ,+-=%等特殊字符）
            query.setQuery("questionPrefix:" + keyword
                    +" OR "+parseText("question", keyword, 8)
                    +" OR "+parseText("answer", keyword, 4)
            );

            //高亮
            query.addHighlightField("question");
            query.addHighlightField("answer");
            query.setHighlightSimplePre("<span class='highlight'>");
            query.setHighlightSimplePost("</span>");
        }
        //返回字段
        query.setFields("id,score,question,answer,categoryId");
    }

    /**
     * 获取 问题库 查询规则
     * @param keyword
     * @return
     */
    private static void setQAApiQueryRule(SolrQueryParam query, String keyword){
        keyword = filterKeyword(keyword); //过滤 关键字 （过滤 ,+-=%等特殊字符）
        query.setQuery("questionPrefix:" + keyword
                        +" OR "+parseText("question", keyword, 8)
                        +" OR "+parseText("answer", keyword, 4)
        );
        //高亮
        query.addHighlightField("question");
        query.addHighlightField("answer");
        query.setHighlightSimplePre("<span class='highlight'>");
        query.setHighlightSimplePost("</span>");
        //返回字段
        query.setFields("id,score,question,answer");
    }


    /**
     * 解析文本
     * @param fieldName
     * @param text
     * @param appendScore
     * @return
     */
    public static String parseText(String fieldName, String text, int appendScore){
        Set<TermBean> terms = WordSegmUtil.getTermList(text);
        StringBuilder expr = new StringBuilder(text.length()+8);
        int dex = 0;
        for (TermBean term : terms) {
            if(dex > 0)
                expr.append(" OR ");
            expr.append(fieldName + ":" + term.getWord());
            if(term.getType().equals("CN_WORD") && appendScore > 0){
                if(appendScore > 0){
                    expr.append("^"+appendScore);
                    appendScore -= 2;
                }
            }
            dex++;
        }
        System.out.println(expr.toString());
        return expr.toString();
    }

    private static List<String> GOODS_CATE_TREE_LIST = new ArrayList<>();
    private static List<String> GOODS_CATE_LIST = new ArrayList<>();

    public static void setGoodsCateList(List<String> goodsCateList) {
        if(CollUtil.isNotEmpty(goodsCateList)){
            GOODS_CATE_LIST.addAll(goodsCateList);
        }
    }
    public static void setGoodsCateTreeList(List<String> goodsCateTreeList) {
        if(CollUtil.isNotEmpty(goodsCateTreeList)){
            GOODS_CATE_TREE_LIST.addAll(goodsCateTreeList);
        }
    }

    /**
     * 获取 商品库 查询规则
     * @param keyword
     * @return
     */
    private static void setGoodsQueryRule(SolrQueryParam query, String keyword){
        //关键字
        if(StrUtil.isBlank(keyword)){
            query.setQuery(DEFAULT_QUERY);
            query.setSort("commentCount", SolrQuery.ORDER.desc);
        }else{
            keyword = filterKeyword(keyword); //过滤 关键字 （过滤 ,+-=%等特殊字符）
            StringBuilder queryStr = new StringBuilder();
            //名称匹配
            queryStr.append("namePrefix:" + keyword + " OR " + parseText("name", keyword, 8));
            //匹配 分类 与 分类树
            Set<String> terms = WordSegmUtil.getCNTermList(keyword);
            if(CollUtil.isNotEmpty(terms)){
                long bg = System.currentTimeMillis();
                for (String term : terms) {
                    if(term.length() > 1){
                        //匹配 分类
                        if(GOODS_CATE_LIST.contains(term)){
                            queryStr.append(" OR categoryName:"+term);
                        }
                        //匹配 分类树
                        if(GOODS_CATE_TREE_LIST.contains(term)){
                            queryStr.append(" OR categoryNameTree:"+term);
                        }
                    }
                }
                long ed = System.currentTimeMillis();
                LogDeBugUtil.debug("分类匹配耗时:"+(ed-bg));
            }
            query.setQuery(queryStr.toString());
        }
        //返回字段
        query.setFields("id,name,price,pic,commentCount,goodRate");
    }


    /**
     * 获取 商品库 建议规则
     * @param keyword
     * @return
     */
    private static void setGoodsSuggestRule(SolrQueryParam query, String keyword){
        keyword = filterKeyword(keyword); //过滤 关键字 （过滤 ,+-=%等特殊字符）
        StringBuilder queryStr = new StringBuilder();
        //名称匹配
        queryStr.append("namePrefix:" + keyword + " OR " + parseText("name", keyword, 8));
        //匹配 分类 与 分类树
        Set<String> terms = WordSegmUtil.getCNTermList(keyword);
        if(CollUtil.isNotEmpty(terms)){
            long bg = System.currentTimeMillis();
            for (String term : terms) {
                if(term.length() > 1){
                    //匹配 分类
                    if(GOODS_CATE_LIST.contains(term)){
                        queryStr.append(" OR categoryName:"+term);
                    }
                    //匹配 分类树
                    if(GOODS_CATE_TREE_LIST.contains(term)){
                        queryStr.append(" OR categoryNameTree:"+term);
                    }
                }
            }
            long ed = System.currentTimeMillis();
            LogDeBugUtil.debug("分类匹配耗时:"+(ed-bg));
        }
        //拼音处理
        List<String> pyArr = PinyinUtil.getPinyinArray(keyword);
        if(!pyArr.isEmpty()){
            // do something
        }
        query.setQuery(queryStr.toString());
        //返回字段
        query.setFields("id,name");
    }


    //设置分页
    private static void setPage(SolrQuery query, PageBean pageBean){
        int pageNo = pageBean.getPageNo();
        if(pageNo < 1)
            pageNo = 1;
        else if(pageNo > MAX_PAGE_NO)
            pageNo = MAX_PAGE_NO;
        query.setStart((pageNo - 1) * pageBean.getPageSize());
        query.setRows(pageBean.getPageSize());
    }


    /**
     * 过滤 关键字 （过滤 ,+-=%等特殊字符）
     * @param keyword
     * @return boolean
     */
    public static String filterKeyword(String keyword) {
        return replaceAll(EmojiUtil.removeTextEmoji(keyword.toLowerCase()), "").trim();
    }
    private static Pattern pattern = Pattern.compile("[+/=?？<>\\-《》\\[\\]【】口@!！@#$%^……&（）(),，;；：:\\|/“”'\"~*]");
    private static String replaceAll(String keyword, String replacement) {
        return pattern.matcher(keyword).replaceAll(replacement);
    }

    public static void main(String[] args) {
        System.out.println();
        String string = "<body>口口213这是一个有各种内容的消息, -2 Hia Hia Hia !!!! xxxx@@@...*)![:呆](@*$&@(&#!)@*)!&$!)@^%@(!&#. 口口口], ";

        System.out.println (filterKeyword(string));
        System.out.println(replaceAll("[:呆]", ""));
    }

}
